﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class BullsAndCowsBeta
{
    static bool isExit = false;
    static SortedDictionary<int, string> scoreBoard = new SortedDictionary<int, string>();
    static HashSet<int> helps = new HashSet<int>();
    static int attempts = 0;
    static int cheats = 0;

    public static int[] GenerateRandomNumber()
    {
        int[] result = new int[4];
        Random randNumber = new Random();
        for (int i = 0; i < result.Length; i++)
        {
            result[i] = randNumber.Next(0, 10);
        }
        return result;
    }

    public static void ShowScoreBoard()
    {
        if (scoreBoard.Count != 0)
        {
            int counter = 0;
            foreach (var item in scoreBoard)
            {
                if (counter == 5)
                {
                    break;
                }
                Console.WriteLine("{0} --> {1}", item.Value, item.Key);
                counter++;
            }
        }
        else
        {
            Console.WriteLine("Scoreboard is empty!");
        }
    }

    public static bool IsCorrectNumber(string playerChoice)
    {
        int num = 0;
        if (playerChoice.Length != 4)
        {
            Console.WriteLine("Incorrect input!");
            return false;
        }
        else
        {
            if (!int.TryParse(playerChoice, out num))
            {
                Console.WriteLine("Incorrect input!");
                return false;
            }
        }
        return true;
    }

    public static void CalculateBullsAndCows(int[] number, string playerChoice, out int bulls, out int cows)
    {
        bulls = 0;
        cows = 0;

        int[] guess = new int[4];
        int[] copyOfNumber = new int[4];
        for (int i = 0; i < number.Length; i++)
        {
            copyOfNumber[i] = number[i];
        }
        for (int i = 0; i < playerChoice.Length; i++)
        {
            guess[i] = int.Parse(playerChoice[i].ToString());
        }
        for (int i = 0; i < guess.Length; i++)
        {
            if (copyOfNumber[i] == guess[i])
            {
                bulls++;
                copyOfNumber[i] = -1;
                guess[i] = -2;
            }
        }

        for (int i = 0; i < guess.Length; i++)
        {
            for (int j = 0; j < copyOfNumber.Length; j++)
            {
                if (guess[i] == copyOfNumber[j])
                {
                    cows++;
                    guess[i] = -2;
                    copyOfNumber[j] = -1;
                }
            }
        }
    }

    public static bool CheckNumber(int[] number, string playerChoice)
    {
        attempts++;
        int bulls = 0;
        int cows = 0;
        CalculateBullsAndCows(number, playerChoice, out bulls, out cows);
        if (bulls == 4)
        {
            Console.WriteLine("Congratulations! You guessed the secret number in {0} attempts and {1} cheats.",
                                attempts, cheats);
            if (cheats == 0)
            {
                Console.Write("Please enter your name for the top scoreboard:");
                string name = Console.ReadLine();
                KeyValuePair<int, string> currentPlayer = new KeyValuePair<int, string>(attempts, name);
                if (!scoreBoard.Contains(currentPlayer))
                {
                    scoreBoard.Add(attempts, name);
                }
            }
            else
            {
                Console.WriteLine("You are not allowed to enter the top scoreboard.");
            }
            return true;
        }
        else
        {
            Console.WriteLine("Wrong number! Bulss: {0}, Cows: {1}", bulls, cows);
        }
        return false;
    }

    public static int[] Help(int[] number, HashSet<int> helps)
    {
        if (helps.Count == 4)
        {
            Console.WriteLine("No more cheating alowed!");
            return null;
        }
        else
        {
            cheats++;
            Random randomNumber = new Random();
            int num = randomNumber.Next(0, 4);
            while (helps.Contains(num))
            {
                num = randomNumber.Next(0, 4);
            }
            helps.Add(num);
            int[] numberHelp = { -1, -1, -1, -1 };
            foreach (var item in helps)
            {
                numberHelp[item] = number[item];
            }
            Console.WriteLine("The number looks like ");
            return numberHelp;
        }
    }

    public static void PlayGame()
    {
        int[] number = GenerateRandomNumber();
        isExit = false;
        cheats = 0;
        attempts = 0;
        Console.WriteLine("Welcome to “Bulls and Cows” game. Please try to guess my secret 4-digit number.\n" +
                            "Use 'top' to view the top scoreboard, 'restart' to start a new game and 'help' to \n" +
                            "cheat and 'exit' to quit the game.");
        do
        {
            Console.Write("Enter your guess or command:");
            string playerChoice = Console.ReadLine();
            switch (playerChoice)
            {
                case "top":
                    ShowScoreBoard();
                    break;
                case "restart":
                    return;
                case "help":
                    Help(number, helps);
                    break;
                case "exit":
                    isExit = true;
                    Console.WriteLine("Good bye!");
                    return;
                default:
                    if (IsCorrectNumber(playerChoice))
                    {
                        if (CheckNumber(number, playerChoice))
                        {
                            return;
                        }
                    }
                    break;
            }

        }
        while (true);
    }

    static void Main(string[] args)
    {
        do
        {
            helps = new HashSet<int>();
            PlayGame();
        }
        while (/*true && */ !isExit);
    }
}
